package net.pimpas.web.jsf.components.validators.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;

import net.pimpas.resourcebundle.exception.MessageKeyNotFoundException;
import net.pimpas.resourcebundle.exception.ResourceBundleNotFoundException;
import net.pimpas.resourcebundle.serviceprovider.ResourceBundleServiceProviderType;
import net.pimpas.web.jsf.components.validators.PimpasValidator;
import net.pimpas.web.jsf.util.ComponentInformation;

public abstract class RegexValidator extends PimpasValidator {
	
	public static final String REGEX_KEY_MESSAGE		= ComponentInformation.COMPONENT_VALIDATE_MESSAGE_KEY+".regex";
	public static final String VALIDATOR_ID				= ComponentInformation.COMPONENT_VALIDATE_ID+".regex";
	public static final String END_MESSAGE_KEY			= ".notMatch"; 

	@Override
	protected void validateComponent(FacesContext context, UIComponent component, Object value) throws ValidatorException {
		
		Regex regexValidator = this.getRegex();
		if(regexValidator.getRegex() == null || "".equals(regexValidator.getRegex())) {
			try {
				String message = this.getBundle().getMessage(this.getClass(), "regexValidatorWrongRegex",
						ResourceBundleServiceProviderType.ERROR, regexValidator.getName(), component.getId());
				throw new RuntimeException(message);
			} catch (ResourceBundleNotFoundException e) {
			} catch (MessageKeyNotFoundException e) {
			}
		}
		
		String v = (String) value;
		Pattern p = Pattern.compile(regexValidator.getRegex());
		Matcher m = p.matcher(v.subSequence(0, v.length()));
		boolean matched = m.matches();
		if(!matched) {
			String message = null;
			// try by id
			message = getMessageKeyByComponentID(component, regexValidator);
			if(message == null)
				// try by component
				message = this.getMessageKeyByComponentValidator(component, regexValidator);
			if(message == null)
				// try by default
				message = this.getMessageKeyByDefault(component, regexValidator);
			
			throw new ValidatorException(new FacesMessage(message));
		}
	}
	
	public abstract Regex getRegex( );
	public abstract String getMessageKey( );
	
	public String getMessageKeyByComponentID( UIComponent component, Regex regex ) {
		String message = null;
		try {
			message = this.getBundle().getMessage(this.getBundleHandler(),
					this.getMessageKey()+END_MESSAGE_KEY+"."+component.getId(),
					ResourceBundleServiceProviderType.VALIDATE, component.getId(), regex.getName(), regex.getRegex());
		} catch (Throwable e) {
			return null;
		}
		
		return message;
	}
	
	public String getMessageKeyByComponentValidator( UIComponent component, Regex regex ) {
		String message = null;
		try {
			message = this.getBundle().getMessage(this.getBundleHandler(),
					this.getMessageKey()+END_MESSAGE_KEY,
					ResourceBundleServiceProviderType.VALIDATE, component.getId(), regex.getName(), regex.getRegex());
		} catch (Throwable e) {
			return null;
		}
		
		return message;
	}
	
	public String getMessageKeyByDefault( UIComponent component, Regex regex) {
		String message = null;
		try {
			message = this.getBundle().getMessage(RegexValidator.class,
					REGEX_KEY_MESSAGE+END_MESSAGE_KEY,
					ResourceBundleServiceProviderType.VALIDATE, component.getId(), regex.getName(), regex.getRegex());
		} catch (Throwable e) {
			return null;
		}
		
		return message;
	}
}